package org.catspaw.cherubim.persistence.dao.spring.jdbc;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import org.catspaw.cherubim.persistence.dao.SearchDao;
import org.catspaw.cherubim.persistence.jdbc.PageSqlHelper;
import org.catspaw.cherubim.persistence.spring.jdbc.NameTrimmedBeanRowMapper;
import org.catspaw.cherubim.util.GenericTypeUtils;

public class SearchSpringJdbcDao extends JdbcDaoSupport implements SearchDao {

	private Class<?>		entityClass;
	private PageSqlHelper	pageSqlHelper;

	public SearchSpringJdbcDao(Class<?> entityClass, PageSqlHelper pageSqlHelper) {
		this.entityClass = entityClass;
		this.pageSqlHelper = pageSqlHelper;
	}

	public SearchSpringJdbcDao(PageSqlHelper pageSqlHelper) {
		this.pageSqlHelper = pageSqlHelper;
	}

	public Object findOne(String sql, Map<String, ?> params) {
		throw new UnsupportedOperationException("not support named parameter");
	}

	public Object findOne(String sql, Object... params) {
		List<?> list = findList(sql, -1, -1, null, params);
		if (!list.isEmpty()) {
			return list.get(0);
		}
		return null;
	}

	public List<?> findList(String sql, Map<String, ?> params) {
		throw new UnsupportedOperationException("not support named parameter");
	}

	public List<?> findList(String sql, Object... params) {
		return findList(sql, -1, -1, null, params);
	}

	public List<?> findList(String sql, int offset, int max, Map<String, ?> params) {
		throw new UnsupportedOperationException("not support named parameter");
	}

	public List<?> findList(String sql, int offset, int max, Object... params) {
		return findList(sql, -1, -1, null, params);
	}

	@SuppressWarnings("unchecked")
	public List<?> findList(final String sql, final int offset, final int max,
			final Map<String, Object> namedParams, final Object[] ordinalParams) {
		return (List<?>) getJdbcTemplate().execute(new ConnectionCallback() {

			public Object doInConnection(Connection con) throws SQLException, DataAccessException {
				String pageSql = pageSqlHelper.createLimitSql(sql, offset, max);
				return getJdbcTemplate().query(pageSql, ordinalParams,
												new NameTrimmedBeanRowMapper(getEntityClass()));
			}
		});
	}

	protected Class<?> getEntityClass() {
		if (entityClass == null) {
			entityClass = (Class<?>) GenericTypeUtils.getSuperClassGenericType(this.getClass());
		}
		return entityClass;
	}

	public PageSqlHelper getPageSqlHelper() {
		return pageSqlHelper;
	}
}
